﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using xbd.DataConvertLib;

namespace lyh.FG2JiaYaZhanDemo
{
    public  class PlcDataService
    {

        /// <summary>
        /// 是否是第一次扫描
        /// </summary>
        public bool IsFirstScan { get; set; } = true;


        /// <summary>
        /// 当前通信是否连接
        /// </summary>
        public bool IsConnected { get;set; }=false;

        /// <summary>
        /// 通信错误次数
        /// </summary>
        public int ErrorTimes { get; set; }


        /// <summary>
        /// 允许的错误次数
        /// </summary>
        public int AllowErrorTimes { get; set; } = 3;

        private S7NetLib s7NetLib = null;

        #region 连接、断开PLC连接
        /// <summary>
        /// 连接PLC
        /// </summary>
        /// <param name="sysInfo"></param>
        /// <returns></returns>
        public OperateResult Connect(SysInfo sysInfo)
        {
            s7NetLib = new S7NetLib(sysInfo.CpuType, sysInfo.IPAddress, sysInfo.Rack, sysInfo.Slot);
             return s7NetLib.Connect();
        }

        /// <summary>
        /// 断开PLC
        /// </summary>
        public void DisConnect()
        {
            if (s7NetLib != null)
            { 
                s7NetLib.DisConnect();
            }
        
        }
        #endregion

        #region 读取PLC数据，封装到类plcData中
        /// <summary>
        /// 读取PLC数据，封装到类
        /// </summary>
        /// <returns></returns>
        public OperateResult<PlcData> ReadPlcData()
        {
            int byteCount = 44;
            OperateResult<byte[]> operateResults = this.s7NetLib.ReadByteArray(xbd.s7netplus.DataType.DataBlock, 1,0,44);
            if (operateResults.IsSuccess&&operateResults.Content.Length==byteCount)
            {
                //数据解析
                PlcData plcData = new PlcData();

                //布尔解析  DB1.DBX0.0  先确定类，再确定方法
                plcData.InPump1State = BitLib.GetBitFromByteArray(operateResults.Content, 0, 0);
                plcData.InPump2State = BitLib.GetBitFromByteArray(operateResults.Content, 0, 1);
                plcData.CirclePump1State = BitLib.GetBitFromByteArray(operateResults.Content, 0, 2);
                plcData.CirclePump2State = BitLib.GetBitFromByteArray(operateResults.Content, 0, 3);
                plcData.ValveInState = BitLib.GetBitFromByteArray(operateResults.Content, 0, 4);
                plcData.ValveOutState = BitLib.GetBitFromByteArray(operateResults.Content, 0, 5);
                plcData.SysRunState = BitLib.GetBitFromByteArray(operateResults.Content, 0, 6);
                plcData.SysAlarmState = BitLib.GetBitFromByteArray(operateResults.Content, 0, 7);


                //浮点解析 DB1.DBD4
                plcData .PressureIn =FloatLib.GetFloatFromByteArray(operateResults.Content, 4);
                plcData.PressureOut = FloatLib.GetFloatFromByteArray(operateResults.Content, 8);
                plcData.TempIn1 = FloatLib.GetFloatFromByteArray(operateResults.Content, 12);
                plcData.TempIn2 = FloatLib.GetFloatFromByteArray(operateResults.Content, 16);
                plcData.TempOut = FloatLib.GetFloatFromByteArray(operateResults.Content, 20);
                plcData.PressureTank1 = FloatLib.GetFloatFromByteArray(operateResults.Content,24);
                plcData.PressureTank2 = FloatLib.GetFloatFromByteArray(operateResults.Content, 28);
                plcData.LevelTank1 = FloatLib.GetFloatFromByteArray(operateResults.Content, 32);
                plcData.LevelTank2 = FloatLib.GetFloatFromByteArray(operateResults.Content, 36);
                plcData.PressureTankOut = FloatLib.GetFloatFromByteArray(operateResults.Content, 40);


                return OperateResult.CreateSuccessResult(plcData);

            }
            else
            {
                return OperateResult.CreateFailResult<PlcData>(operateResults.Message);
            }
        }
        #endregion

        #region 写入PLC数据
        public bool SysReset()
        { 
            string controlAddress = "DB1.DBX101.4";
            bool result = s7NetLib.WriteVariable(controlAddress, true).IsSuccess;
            Thread.Sleep(50);
            result &= s7NetLib.WriteVariable(controlAddress, false).IsSuccess;
            return result;
        }
        #endregion

        #region 泵控制

        /// <summary>
        /// 1号进水泵控制
        /// </summary>
        /// <param name="state">需要开或者关</param>
        /// <returns></returns>
        public bool InPump1Control(bool state)
        {
            string  startAddress = "DB1.DBX100.0";
            string stopAddress = "DB1.DBX100.1";

            string controlAddress=state? startAddress:stopAddress;
            //写入一个高脉冲，在写入一个低脉冲
            bool result = s7NetLib.WriteVariable(controlAddress, true).IsSuccess;
            Thread.Sleep(50);
            result &= s7NetLib.WriteVariable(controlAddress, false).IsSuccess;
            return result;        
        }

        /// <summary>
        /// 2号进水泵控制
        /// </summary>
        /// <param name="state">需要开或者关</param>
        /// <returns></returns>
        public bool InPump2Control(bool state)
        {
            string startAddress = "DB1.DBX100.2";
            string stopAddress = "DB1.DBX100.3";

            string controlAddress = state ? startAddress : stopAddress;

            bool result = s7NetLib.WriteVariable(controlAddress, true).IsSuccess;
            Thread.Sleep(50);
            result &= s7NetLib.WriteVariable(controlAddress, false).IsSuccess;
            return result;
        }

        /// <summary>
        /// 1号循环泵控制
        /// </summary>
        /// <param name="state">需要开或者关</param>
        /// <returns></returns>
        public bool CirclePump1Control(bool state)
        {
            string startAddress = "DB1.DBX100.4";
            string stopAddress = "DB1.DBX100.5";

            string controlAddress = state ? startAddress : stopAddress;

            bool result = s7NetLib.WriteVariable(controlAddress, true).IsSuccess;
            Thread.Sleep(50);
            result &= s7NetLib.WriteVariable(controlAddress, false).IsSuccess;
            return result;
        }

        /// <summary>
        /// 2号循环泵控制
        /// </summary>
        /// <param name="state">需要开或者关</param>
        /// <returns></returns>
        public bool CirclePump2Control(bool state)
        {
            string startAddress = "DB1.DBX100.6";
            string stopAddress = "DB1.DBX100.7";

            string controlAddress = state ? startAddress : stopAddress;

            bool result = s7NetLib.WriteVariable(controlAddress, true).IsSuccess;
            Thread.Sleep(50);
            result &= s7NetLib.WriteVariable(controlAddress, false).IsSuccess;
            return result;
        }


        /// <summary>
        /// 进水阀控制
        /// </summary>
        /// <param name="state">需要开或者关</param>
        /// <returns></returns>
        public bool ValveInControl(bool state)
        {
            string startAddress = "DB1.DBX101.0";
            string stopAddress = "DB1.DBX101.1";

            string controlAddress = state ? startAddress : stopAddress;

            bool result = s7NetLib.WriteVariable(controlAddress, true).IsSuccess;
            Thread.Sleep(50);
            result &= s7NetLib.WriteVariable(controlAddress, false).IsSuccess;
            return result;
        }


        /// <summary>
        /// 出水阀控制
        /// </summary>
        /// <param name="state">需要开或者关</param>
        /// <returns></returns>
        public bool ValveOutControl(bool state)
        {
            string startAddress = "DB1.DBX101.2";
            string stopAddress = "DB1.DBX101.3";

            string controlAddress = state ? startAddress : stopAddress;

            bool result = s7NetLib.WriteVariable(controlAddress, true).IsSuccess;
            Thread.Sleep(50);
            result &= s7NetLib.WriteVariable(controlAddress, false).IsSuccess;
            return result;
        }

        #endregion
    }
}
